home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr48 / ned100.zip / NEWEDIT.DOC < prev    next >
Text File  |  1993-04-08  |  44KB  |  1,104 lines

  1. INTRODUCTION
  2. ------------
  3.  
  4. I originally started this project to add a wordwrap feature to
  5. the Turbo Vision EDITORS unit.  To make matters worse, I'm new
  6. to Pascal, and trying to learn the language, Turbo
  7. Vision, and event driven programming was just a bit of a
  8. hurdle.  So I asked for help, LOTS of help, and the next thing
  9. I knew I was working with people I've never met trying to
  10. create a full-blown IDE compatible wordprocessor, with the
  11. wordwrap!
  12.  
  13. Well, it got done, minus the IDE select text features such as
  14. read/write/indent blocks, etc.  If nothing else, it was one way
  15. of learning three things at once.  We all had a lot of fun,
  16. probably at my expense <grin>.
  17.  
  18. NEWEDIT.PAS is a complete replacement for the original EDITORS
  19. unit.  It's major contribution is the implementation of a
  20. wordwrap feature.  It also has several other features, which
  21. will be outlined below.
  22.  
  23. If you decide to use the NEWEDIT unit with your applications,
  24. be sure you change your use clause from "uses Editors" to "uses
  25. NewEdit" in all code modules that require the editor.  Those
  26. modules included in the NED100.ZIP file already do this.
  27.  
  28. You should NOT overwrite your original EDITORS.PAS file!  Keep
  29. it for reference should you decide to dig into the work I have
  30. done and add your own features.  Comparison is a learning tool!
  31.  
  32. The rest of this document deals with the modifications I have
  33. made, discussing how they work, and whatever quirks you should
  34. be familiar with.  A command summary is also provided of all
  35. the NEWEDIT options.  Last of all, a brief discussion is given
  36. that explains how to implement your own customized key
  37. commands.
  38.  
  39. Please note that this document is NOT written for users.  It is
  40. written for you, the programmer.  A lot of the information
  41. contained herein would severely confuse your users due to its
  42. technical nature.  Don't make life harder on them by cutting
  43. and pasting the current text to make a quick users guide.  Take
  44. the time and effort to write your own, and make it as simple as
  45. possible.
  46.  
  47.  
  48.  
  49. HOW TO USE IT
  50. -------------
  51.  
  52. I figured I'd put this right up front so you can jump right into it.
  53. You can use the program either as is, or you can yank out NEWEDIT and
  54. simply patch it into your application.  I'll discuss both methods.
  55.  
  56.  
  57.  
  58. Using NEDEMO
  59. ------------
  60.  
  61. Your best bet is to create a directory and dump all the NED100.ZIP files
  62. into it.  Baring that, put the files wherever you want.
  63.  
  64. Next, ensure that all the units called in NEDEMO.PAS are available for
  65. compilation.  Now, compile the NEDEMO.PAS source.  All the other units
  66. will compile.  If you get an error message stating that a unit can't be
  67. compiled, fix your Options|Directories so the path to the unit is
  68. correct.  Or, take the unit TPU or PAS file and put it in your
  69. compilation directory.
  70.  
  71.  
  72.  
  73. Plug Into Your Application
  74. --------------------------
  75.  
  76. The NEWEDIT unit is plug-in compatible with the standard EDITORS unit.
  77. If you're not interested in the NEDEMO program, but want to use the
  78. NEWEDIT unit as is, you can easily patch it into your application.
  79.  
  80. You will need the EDITPKG.PAS and NEWEDIT.PAS programs.  NEWEDIT.PAS is
  81. the actual editor.  EDITPKG.PAS contains all the dialogs and calls to
  82. the clipboard and editor.
  83.  
  84.  
  85. 1)  In your main application INIT constructor, insert this line BEFORE
  86.     you use "TApplication.Init":
  87.  
  88.         EditPkg.Initialize_The_Editor;
  89.  
  90.     Then load any previous desktop and disable any editor commands you
  91.     don't want the user to have immediate access to.
  92.  
  93.     Last of all, initialize the clipboard with this code:
  94.  
  95.         EditPkg.Initialize_The_Clipboard;
  96.  
  97.     Look at the T_EditDemo.Init code in NEDEMO.PAS if you have
  98.     questions.
  99.  
  100. 2)  In your main application HandleEvent code, insert this line for
  101.     opening new files:
  102.  
  103.         cmNew          : EditPkg.Open_Editor ('', True);
  104.  
  105. 3)  In your main application HandleEvent code, insert this line for
  106.     opening existing disk files:
  107.  
  108.         cmOpen         : EditPkg.Run_The_Editor;
  109.  
  110. 4)  If you write the desktop to disk, for any reason, be sure you
  111.     deallocate and reallocate the clipboard.  Failure to do so will
  112.     cause your desktop file to start growing and growing!  Insert this
  113.     code around your save desktop code:
  114.  
  115.  
  116.       EditPkg.Deallocate_The_Clipboard;
  117.  
  118.       {Your code goes here!}
  119.  
  120.       EditPkg.Initialize_The_Clipboard;
  121.  
  122.  
  123.     If you have any questions on this, look in the NEDEMO.PAS
  124.     T_EditDemo.Save_Desktop function for how it should be done.
  125.  
  126. 5)  In your application's DONE destructor, be sure you deallocate the
  127.     editor buffer AFTER "TApplication.Done":
  128.  
  129.       TApplication.Done;
  130.       EditPkg.Deallocate_The_Editor;
  131.  
  132. 6)  Check all units to ensure that "uses EDITORS" is changed to "uses
  133.     NEWEDIT".
  134.  
  135. 7)  If you want to use my help system, the EDITHELP.TXT file will
  136.     probably have to be revised to suit your hc???? constant naming
  137.     convention.   That, or you'll have to write your own.
  138.  
  139.  
  140. It's not as difficult as it sounds.  I've done it with a minimum of
  141. fuss, and several of the beta testers have done the same thing.
  142.  
  143.  
  144.  
  145. CREATING HELP
  146. -------------
  147.  
  148. The file EDITHELP.TXT contains the source for the context sensitive help
  149. system.  You must compile it with the TVHC.EXE program to make it
  150. functional.  Included with NED100 is a MAKEHELP.BAT file.  Simply type
  151. MAKEHELP to generate a usable help file.  Ensure that TVHC is in your
  152. directory or path.
  153.  
  154. I've done things a bit different than normal here, so some explanation
  155. might be in order.
  156.  
  157. All cm???? and hc???? constants are in the CMDFILE.PAS file. Seeing as
  158. I've mixed these constants, I didn't want CMDFILE.PAS to be overwritten
  159. by the TVHC program.  What I do in the batch file is to let TVHC
  160. generate an EDITHELP.PAS, EDITHELP.TPU, and EDITHELP.HLP file.  I then
  161. rename the EDITHELP.HLP file to NEDEMO.HLP and erase the EDITHELP.TPU
  162. file.  I keep the EDITHELP.PAS file as a handy alphabetical reference.
  163.  
  164. So, the short of it is that NEDEMO requires that the CMDFILE unit be
  165. available and that the help file be named NEDEMO.HLP.
  166.  
  167.  
  168.  
  169. CODING STYLE
  170. ------------
  171.  
  172. Every one has their way of doing things, and I'm as guilty as the next
  173. person.  The only reason I bring it up is that coding style may look
  174. very foreign to those who do it Borland's way.  This is not a
  175. justification, just an explanation!
  176.  
  177. I code the way I do so that I can quickly convert code between C,
  178. PASCAL, and Ada.
  179.  
  180. I don't put all of my if/elses on one line.  I like to see which
  181. condition is met when I'm debugging.
  182.  
  183. I use lots of white space so things don't look as bad as they really
  184. are<grin>.
  185.  
  186. I use 43/50 column mode and print in compressed mode, therefore my code
  187. does tend to go beyond the right margin.
  188.  
  189. Last of all, and this is probably important to some of you, I use fully
  190. qualified variable and procedure/function names.  I HATE having to
  191. figure out where a variable or procedure/function is.  Where I work,
  192. people are summarily shot for failing to do so!
  193.  
  194.  
  195.  
  196. WHEN IS A BUG NOT A BUG?
  197. ------------------------
  198.  
  199. When it's a feature, of course!  I've seen several so-called bug
  200. reports describing what the authors consider to be bugs in the
  201. EDITORS unit, when in fact they are reporting features.
  202. Granted, there are some bugs there, and the service these
  203. authors provide by reporting them is invaluable.
  204.  
  205. To set the record straight, the following two items are NOT
  206. bugs!
  207.  
  208. 1)  Pressing ^T will in some instances delete more than just the
  209.     word you want deleted.
  210.  
  211.     Sorry, this is NOT a bug!  The Editors unit defines a
  212.     particular character set.  Any character not in that
  213.     character set is a "non-character".  ^T works like this:
  214.  
  215.     a)  Delete from the cursor position all characters to the
  216.         first character not defined in our character set.  That
  217.         takes care of the current word.
  218.  
  219.     b)  Now we need to delete all characters NOT in the
  220.         character set to the next character that IS in the
  221.         character set.  That deletes the "blank space" between
  222.         words.
  223.  
  224.     Step B is what most people consider the "bug" for you will
  225.     delete characters that are not in the character set between
  226.     words.  It's the way the Editor was designed!  You may not
  227.     like it, but that doesn't make it a bug!
  228.  
  229.     This supposed "bug" is not a problem with NEWEDIT.  In the
  230.     process of changing the character set to acoomodate
  231.     wordwrap, it has become a non-issue.  I just wanted users to
  232.     be aware of the difference in NEWEDIT and EDITORS.
  233.  
  234. 2)  Selecting text and then pressing a key deletes selected
  235.     text.
  236.  
  237.     This is a feature that allows you to quickly do a FIND and
  238.     then type in new text to replace old text.  Yes Virginia,
  239.     you should use SEARCH/REPLACE, but there are times when this
  240.     little feature used in conjunction with FIND is invaluable.
  241.     It also allows you to mark text for quick selection and
  242.     deleting.
  243.  
  244.     Several supposed "fixes" for this feature will do nothing
  245.     but clobber your FIND and/or SEARCH/REPLACE capabilities.
  246.  
  247.     So what if you accidently erase the selected text -- ^Undo
  248.     it!
  249.  
  250.     I have deliberately retained this feature in NEWEDIT.
  251.     Please do not report to me that FIND and/or SEARCH/REPLACE
  252.     no longer work because you tried to incorporate one of the
  253.     "bug fixes" for this alleged problem!
  254.  
  255.  
  256.  
  257. 43/50 LINE VIDEO
  258. ----------------
  259.  
  260. Have added the capability of using 43/50 line screens if you have EGA or
  261. better.  The option can be found in the OPTIONS menu.  It is
  262. automatically disabled if the user doesn't have the capability.
  263.  
  264. Note that Load/Store remembers what video mode you were in and resets
  265. the program to that mode when the desktop is automatically loaded.
  266.  
  267.  
  268.  
  269. AUTOINDENT
  270. ----------
  271.  
  272. The AutoIndent command has been changed from ^O to ^QI.  I did
  273. this for two reasons.  The first is that ^O is right next to
  274. ^I, the tab key.  The other is that ^QI is the WordStar
  275. sequence for this feature.  It keeps the user out of trouble,
  276. and it makes the editor conform more to WordStar, which I
  277. presume was Borland's original intent.
  278.  
  279.  
  280.  
  281. CENTERING TEXT
  282. --------------
  283.  
  284. A line of text may be centered by using ^OC.  Centering is
  285. based on the setting of the Right_Margin.  If a line is blank,
  286. or the length of the line exceeds the Right_Margin value,
  287. nothing will happen.  Spaces at the beginning of lines are not
  288. used when calculating the line length.
  289.  
  290. The cursor will be moved to the end of the line after it has
  291. been centered.
  292.  
  293.  
  294.  
  295. CHARACTER SET
  296. -------------
  297.  
  298. The original EDITORS unit had the following character set:
  299.  
  300.   WordChars: set of Char = ['0'..'9', 'A'..'Z', '_', 'a'..'z'];
  301.  
  302. This implementation of the NEWEDIT unit has changed the
  303. character set to be to the following:
  304.  
  305.   WordChars: set of Char = ['!'..#255];
  306.  
  307. This was done to allow simpler coding for the wordwrap feature.
  308. Note that the tab character is no longer considered a valid
  309. character.  This is described in further detail later in the
  310. document.  Also note that jumping from word to word will no
  311. longer bypass extended ASCII characters.
  312.  
  313.  
  314.  
  315. COLORS
  316. ------
  317.  
  318. To be quite honest, the whole GetPalette color business is
  319. beyond me and the TV documentation, while going into depth on
  320. the subject, doesn't lend to clarifying the issue.  So, I've
  321. done a quick and dirty change of the whole blasted palette.
  322.  
  323. NEDEMO.PAS has a constant called New_Colors.  It contains a
  324. whole new color scheme.  As a programmer, you have several
  325. options available to you.
  326.  
  327. You can keep things like I've got them.
  328.  
  329. You can change them back to the TV defaults by deleting the
  330. New_Colors constant and the T_EditDemo.GetPalette procedure in
  331. its entirety.
  332.  
  333. You can open up APP.PAS and replace the CColor constant data
  334. with the New_Colors data to make ALL your applications have
  335. these new colors.  Just make sure you delete New_Colors and
  336. T_EditDemo.GetPalette so you don't duplicate things.
  337.  
  338. You can change New_Colors to use your own color scheme.
  339.  
  340. Play around and see what you would prefer.
  341.  
  342. The ASCII file COLORS.ASC is being distributed with NED100.ZIP
  343. to show you how to change the color palette.  It was originally
  344. written by CIS member Steve Shafer, 71121,1771, and is available with
  345. NED100 by his permission.
  346.  
  347.  
  348.  
  349. CONSTANTS
  350. ---------
  351.  
  352. I've put all of the NEWEDIT constants that support the new features in
  353. the 200 range.  I did this to allow programmers to enable/disable these
  354. commands in any menu system they design.
  355.  
  356.  
  357.  
  358. CTRL-BACKSPACE
  359. --------------
  360.  
  361. Added this feature to allow two options for deleting text from
  362. the cursor to the left margin.  You can use ^BackSpace or ^QH.
  363.  
  364.  
  365.  
  366. CTRL-HOME AND CTRL-END
  367. ----------------------
  368.  
  369. To add compatibility with the regular IDE editor, I have added
  370. the ability to jump to the top and bottom of a page.
  371. [Ctrl]-[Home] will take the cursor to the top of a page and
  372. [Ctrl]-[End] will take the cursor to the bottom of a page.
  373.  
  374. Note that the cursor does NOT go to the first position in the
  375. line. The actual position it ends up at is based on the current
  376. position of the cursor on the current line when one of these
  377. key sequences are pressed, and the length of the new line it
  378. ends up on.
  379.  
  380.  
  381.  
  382. DESKTOP MENU
  383. ------------
  384.  
  385. The user should have a menu that allows them to load and store
  386. the desktop, so I added a DESKTOP menu.  I've also added the
  387. 43/50 line mode video toggle to this menu.
  388.  
  389.  
  390.  
  391. DOCUMENT REFORMAT
  392. -----------------
  393.  
  394. Pressing ^QU will allow you to reformat a document from either
  395. the current line, or the beginning of a document, to the end of
  396. the document.  A dialog box appears with radio buttons asking
  397. you where you want to start reformatting.
  398.  
  399. You must be VERY careful when using this option.  It is based
  400. on the paragraph reformat feature.  You will note in that
  401. section that reformatting is based on the indentation of the
  402. first line in a paragraph, and whether or not the AutoIndent
  403. feature is toggled on.
  404.  
  405. Your screen will scroll to follow the reformat process. This
  406. allows the user to know something is happening, instead of just
  407. having the system lock up while text is reformatted.
  408.  
  409.  
  410.  
  411. END OF LINE SPACES
  412. ------------------
  413.  
  414. Spaces at the end of lines are automatically removed.  This was
  415. required to make the wordwrap and reformat feature work
  416. properly.  Spaces on blank lines are also removed.  Only the
  417. CR/LF is kept.
  418.  
  419. Spaces are NOT removed until the cursor has traveled over or
  420. onto a line.  Therefore, if you load a file created by another
  421. ASCII editor that does not strip spaces, they will remain in
  422. the document until you move through the document with the
  423. cursor keys.
  424.  
  425.  
  426.  
  427. INDICATOR LINE
  428. --------------
  429.  
  430. The window TIndicator line has been modified.  Instead of that
  431. stupid character that pops up to indicate the document has been
  432. modified, an "M" now appears.  Also, an "I" appears when
  433. AutoIndent is active, and a "W" pops up when wordwrap is on.
  434. This means I had to take some space away from the cursor stats,
  435. but, with only 64K available, I don't think there will be a problem
  436. unless the user is entering some weird text.
  437.  
  438.  
  439.  
  440. INSERT NEW LINE
  441. ---------------
  442.  
  443. Pressing ^N will insert a CR/LF pair at the current cursor
  444. position.  All characters AT the cursor and to the end of the
  445. line will be moved down to the next line.  The difference
  446. between pressing ^N and [Enter] is that with ^N the cursor
  447. stays at its current position and does NOT move down to the
  448. next line.  The only exception to this would be if the cursor
  449. was at the end of a line that has its spaces removed when ^N is
  450. pressed.  In that case, the cursor goes to the new end of line.
  451.  
  452. This feature was added to allow further compatibility with the
  453. current IDE.
  454.  
  455.  
  456.  
  457. JUMP TO LINE NUMBER
  458. -------------------
  459.  
  460. Pressing ^JL will allow the user to jump to a particular line
  461. number.  A dialog box will appear that requests the user input
  462. a line number to jump to.  Valid entries range from 1 to 9999.
  463. I believe 9999 is a high enough range.  If someone thinks it
  464. should be larger, please let me know.
  465.  
  466. The dialog box differs from the right margin and preset tab
  467. dialogs in that the initial Line_Number value is always blank.
  468. However, once the user inputs a value it is remembered, thereby
  469. allowing the user to jump to the same line number after they
  470. scroll around the text.
  471.  
  472.  
  473.  
  474. LOAD/STORE OPERATIONS
  475. ---------------------
  476.  
  477. The original load/store bug in EDITORS.PAS has been fixed.
  478. In addition, new Read/Write streams have been incorporated
  479. in TEditor.Load and TEditor.Store to allow saving of the new
  480. variables in the TEditor object.
  481.  
  482.  
  483.  
  484. MEMORY
  485. ------
  486.  
  487. In the original Borland EDITORS unit, you are allowed to define how much
  488. of an edit buffer you can set aside on the heap.  This buffer size
  489. determines how many editor windows you can have open at one time.  The
  490. default in the EDITORS unit was to take the buffer size the programmer
  491. wanted, and to then allocate all available heap to the editors, and
  492. leave the editors buffer size as the free space.  So, you got lots of
  493. memory so you could open up lots of editor windows.
  494.  
  495. Not everyone wants all that heap set aside for the editors.  The EDITPKG
  496. unit maintains the Borland default, but by changing two lines in the
  497. EDITPKG.Initialize_The_Editor procedure you can set aside exactly how
  498. much buffer space you want for the editor, and ONLY that buffer space,
  499. leaving the rest of the heap available to your applications.  Just search
  500. for the label "HEAP" to find these two lines.
  501.  
  502.  
  503.  
  504. MENUS
  505. -----
  506.  
  507. How to create menus is pretty much covered in the TurboVision
  508. documentation, and I'm not going to cover it here.  What I would
  509. like to state is that I've provided ready-to-use code in the
  510. NEWEDIT unit and the NEDEMO program that will allow you to
  511. toggle your menu options on/off.  All you need to do is
  512. uncomment the code I have in place to make use of toggling your
  513. new menu options on/off.
  514.  
  515. The T_EditDemo.Init constructor in NEDEMO contains the original
  516. disabling code.
  517.  
  518. The TFileEditor.UpdateCommands procedure in NEWEDIT contains the
  519. actual updating code.
  520.  
  521. WARNING!!!!  You will pay a HEAVY price for each additional
  522.              SetCmdState (Command, True) line you uncomment in
  523.              procedure TfileEditor.UpdateCommands.  The price is
  524.              in system response time.  Uncommenting all the
  525.              lines will turn your fast 64K editor into a slow
  526.              clunky piece of junk!  Of course, you don't really
  527.              need to disable/enable menu options for editor
  528.              menus you might design.  My advice is to either
  529.              keep the menu minimal and uncomment only what you
  530.              really need, or leave all your editor menu options
  531.              enabled at all times.
  532.  
  533.  
  534.  
  535. PARAGRAPH REFORMAT
  536. ------------------
  537.  
  538. This feature is available to the user via the ^B key.  It works
  539. regardless of whether or not wordwrap is active.  Reformatting
  540. is based on the current right margin position.  As with
  541. wordwrap, reformatting is not possible if the cursor is beyond
  542. the right margin position.  An error dialog will appear.
  543.  
  544. Paragraph reformat also works with the AutoIndent feature.
  545. However, it is important to note that the reformat process is
  546. based on the current line the cursor happens to be sitting on
  547. when ^B is pressed.  Therefore, if you use hanging paragraphs
  548. (a paragraph where the first line sticks out further to the
  549. left margin than the rest of the paragraph) you need to be
  550. careful.  If the cursor is on the first line of the paragraph,
  551. the reformatting takes place according to that line's left
  552. margin setting.  This is a feature, not a bug.  Try the same
  553. thing with MicroStar or SideKick and you'll see what I mean.
  554.  
  555. If AutoIndent is on, and the paragraph is so indented that
  556. reformatting encounters a word that will not fit on the line
  557. according to the left and right margin settings, an error
  558. dialog will appear.  However, any reformatting accomplished
  559. prior to this situation will have taken effect.  The cursor
  560. should stop on the word it couldn't wrap.  This should preclude
  561. the reformatting process locking up the system because it can't
  562. wrap a word that is too long.
  563.  
  564. The cursor will end up at the first blank line after the
  565. paragraph when you press ^B.  Therefore, you can reformat
  566. paragraphs in quick succession.
  567.  
  568. Note that unlike some other editors, this implementation of
  569. paragraph reformatting will retain double spaces after periods,
  570. exclamation points, question marks, and colons.  If you are in
  571. the habit of only using one space, it's not syntactically
  572. correct.  Two spaces will be inserted instead, providing the
  573. cursor was sitting on one of these punctuation marks when the
  574. reformatting process was doing its thing.  Otherwise, no change
  575. will be made to your original text.
  576.  
  577. I've noticed that if the editor is almost filled to capacity
  578. and the user tries to do a ^B on one of the last paragraphs,
  579. the reformatting doesn't work properly.  I have no idea what to
  580. do about this, as I suspect it has something to do with buffers
  581. and all.
  582.  
  583.  
  584.  
  585. PLACE MARKERS
  586. -------------
  587.  
  588. The editor now allows the user to set place markers within the
  589. document.  ^K#, where # is a value between 1 and 0 on the
  590. keyboard, allows the user to set up to 10 place markers.  The
  591. user can jump to a place marker by pressing ^Q#, where # is a
  592. value between 1 and 0 on the keyboard.
  593.  
  594. Place markers are not visible, but they are there
  595. none-the-less.  They are maintained in an array called
  596. Place_Marker, which is contained in the TEditor object.
  597.  
  598. Place markers are constantly updated as the user inserts and
  599. deletes text.  If a place marker is contained within text that
  600. is deleted, it is set back to zero.  The cursor key goes
  601. nowhere if it encounters a place marker with a zero value as a
  602. result of a ^Q# request.  Of course, this also means you can
  603. not set a place marker in column 1 of line 1, for it is the 0th
  604. position in the document.  Use [Ctrl]-[PgUp] instead!
  605.  
  606.  
  607.  
  608. PRESET TABS
  609. -----------
  610.  
  611. A preset tab feature has been implemented, allowing the user to
  612. define up to 74 tab stops.  The ^OI keys will bring up a tab
  613. stop dialog box.  The box has a ruler across the top and an
  614. input line beneath the ruler.
  615.  
  616. To set tabs, the user should place a character in the input
  617. line directly beneath the ruler setting where a tab is wanted.
  618. The input line is a normal TInputLine, therefore its behavior
  619. follows the norm.  Note that if the input line is filled with
  620. spaces the user will not be able to enter any data.  To help
  621. alleviate this situation, the TInputLine data is stripped of
  622. all unnecessary spaces after the last tab stop every time the
  623. user exits the dialog box.
  624.  
  625. The data is placed in a string variable called Tab_Settings
  626. which is contained in the TEditor object.
  627.  
  628. Tab_Settings is automatically initialized to increments of 7.
  629. The initialization takes place in TEditor.Init.
  630.  
  631. Pressing [Esc] or the OK dialog button will keep the current
  632. Tab_Settings.
  633.  
  634.  
  635.  
  636. RIGHT MARGIN
  637. ------------
  638.  
  639. The user can set the right margin of the document.  This is
  640. done by pressing the ^OR sequence.  A dialog box will appear
  641. asking the user to enter a right margin value.  The current
  642. value will be shown each time the dialog comes up.  The default
  643. value is 76.  The programmer must change this to something else
  644. in the TEditor.Init code if they want a different value.  The
  645. user has only three options; enter the value, press the OK
  646. button, or press [Esc].  Pressing OK or [Esc] will keep the
  647. current value.  Valid entries are 10 through 255.  If the user
  648. enters a value that is not within this range, the current value
  649. is maintained.  No error message will be given!
  650.  
  651. The right margin value is contained in the TEditor object.  The
  652. variable is called Right_Margin.
  653.  
  654.  
  655.  
  656. SAVE FEATURES
  657. -------------
  658.  
  659. There are several more save features than normal.  I've tried
  660. to implement the most important WordStar commands that apply to
  661. saving the document.  I've also retained Borland's current
  662. features.
  663.  
  664.  
  665.   [F2] or ^KS - cmSave     - Save text to current file and
  666.                              resume editing.
  667.   ^KF         - cmSaveAs   - Save text to another file.
  668.   ^KD or ^KX  - cmSaveDone - Save text to current file and exit
  669.                              editor.
  670.  
  671. Note that where cmSaveAs used to be accessible only through a
  672. menu option like "Save As...", it is now accessible to the
  673. user, regardless of the programmers menu system, via the ^KF.
  674. This applies to all the save features.  They are all accessible
  675. to the user.
  676.  
  677.  
  678.  
  679. SCROLL DOWN
  680. -----------
  681.  
  682. Pressing ^Z emulates the IDE function of scrolling the screen
  683. up while maintaining the cursor position.  If the original
  684. cursor position scrolls off the screen, the cursor scrolls down
  685. a line.  This forces the cursor to stay in the upper left
  686. corner of the screen should the original cursor position scroll
  687. away.
  688.  
  689.  
  690.  
  691. SCROLL UP
  692. ---------
  693.  
  694. Pressing ^W emulates the IDE function of scrolling the screen
  695. down while maintaining the cursor position.  If the original
  696. cursor position scrolls off the screen, the cursor scrolls up a
  697. line.  This forces the cursor to stay in the lower left corner
  698. of the screen should the original cursor position scroll away.
  699.  
  700.  
  701.  
  702. SELECT WORD
  703. -----------
  704.  
  705. Pressing ^KT will highlight the current word the cursor is sitting on.
  706. This function was added to maintain compatibility with the IDE.
  707.  
  708. The word is marked from the current cursor position to the next space or
  709. end of line, whichever comes first.  The marked word is put into the
  710. clipboard without further effort on the users part.  Marking works in
  711. the normal manner, i.e., it disappears the moment you move the cursor.
  712.  
  713. Note that NOTHING will happen if you try to use this command when the
  714. cursor is sitting on a space or the end of a line.
  715.  
  716.  
  717.  
  718. TABS
  719. ----
  720.  
  721. I realize that Borland allows the tab (#9) character in the
  722. original editors package.  They probably did this to allow a
  723. maximal amount of data to fit in a small 64K buffer.  However,
  724. the current implementation of this NEWEDIT unit does not allow
  725. tabs.  I did this to make the added features a simpler exercise
  726. in coding.
  727.  
  728. Tab works in two different ways.
  729.  
  730. When in INSERT mode, the cursor will attempt to go to the next
  731. tab stop, happily INSERTING SPACES as it looks for that next
  732. stopping point.  If it is at the last tab stop, it stops
  733. inserting spaces and takes a big jump to the first character of
  734. the next line.  Try to keep tab use to a minimum when the
  735. cursor is in insert mode.  You eat up valuable buffer space
  736. real quick!
  737.  
  738. When in OVERSTRIKE mode, the cursor will attempt to go to the
  739. next tab stop, happily skipping over characters as it looks for
  740. that next stopping point.  If it is at the last tab stop, OR
  741. the line is too short to allow it to reach the next tab stop,
  742. it takes a big jump to the first character of the next line.
  743.  
  744. I think you'll see that if you set your tabs right, you can
  745. quickly indent a whole paragraph deeper than it already is.
  746. Also, you don't come to a screeching halt.  If in OVERSTRIKE
  747. mode you can move through a document real quick.
  748.  
  749.  
  750.  
  751. TVFORMS DEMO AND PDEMO OBJECT
  752. -----------------------------
  753.  
  754. So, you want wordwrap in your PDEMO object?  No problem!
  755. I'll use the GENPARTS.PAS program for the TVFORMS demo program
  756. as an example.  Find the line in the function "MakeForm" that
  757. looks like this:
  758.  
  759.      C := New (PMemo, Init (R, nil, PScrollBar(C), nil, DescrLen));
  760.  
  761. Now, add these two lines right after it:
  762.  
  763.      PMemo(C)^.Word_Wrap := TRUE;
  764.      PMemo(C)^.Right_Margin := R.B.X - R.A.X;
  765.  
  766. Now you've got wordwrap!  You simply type cast the Wordwrap
  767. variable to default to TRUE and Right_Margin for where you want
  768. wordwrap to occur, and that's all there is to it!  Just
  769. remember to do this for each and every PMemo you want wordwrap
  770. for.
  771.  
  772.  
  773.  
  774. UNDO
  775. ----
  776.  
  777. ^U is the normal undo feature for the NEWEDIT unit.  However,
  778. to maintain compatibility with the IDE editor, I have also
  779. provided a ^QL option.  They both do the same job.
  780.  
  781.  
  782.  
  783. WORDWRAP
  784. --------
  785.  
  786. Wordwrap is toggled on/off via the ^OW sequence.  When wordwrap
  787. is on, a "W" appears on the status line.  Wordwrap is fast, and
  788. should keep up with the most fluid typist.  There should be no
  789. "jerkiness" in the wrap effect.
  790.  
  791. Wordwrap is based on the "push the line out to the right until
  792. the cursor reaches the current right margin setting" principle.
  793. Therefore, if you are on a line and inserting text, the text
  794. will be pushed beyond the right margin until the cursor gets
  795. there, at which point the text beyond the cursor is wrapped.
  796.  
  797. The right margin is considered to be the current right margin
  798. value + 1.  For example, if your right margin is set to 69,
  799. then the cursor CAN go to column 70.  Trying to exceed column
  800. 70 will cause wordwrap to occur.
  801.  
  802. Wordwrap will not work if the cursor is beyond the current
  803. right margin setting.  In this event, an error dialog box will
  804. appear.
  805.  
  806. Wordwrap will also work with the AutoIndent mode turned on.  In
  807. this case, the cursor goes to the same first character position
  808. on the new line as the line it was on when wrap occurred.
  809.  
  810. If you try to type a blank line of spaces to the right margin,
  811. wordwrap will remove the spaces and insert just a CR/LF pair.
  812. Wordwrap will also bring up an error message if you try to type
  813. in an entire line out to the right margin without spaces.
  814.  
  815.  
  816.  
  817. COMMAND SUMMARY
  818. ---------------
  819.  
  820. The following list contains all the commands available in this
  821. implementation of the Turbo Vision NEWEDIT unit.
  822.  
  823. Command                TV Command     Description
  824. --------------------   -------------  ------------------------------------------------
  825.  
  826.           [Ctrl]-[A] - cmWordLeft     Move cursor left to previous word.
  827.           [Ctrl]-[B] - cmReformPara   Reformat paragraph to current margins.
  828.           [Ctrl]-[C] - cmPageDown     Page down one screen.
  829.           [Ctrl]-[D] - cmCharRight    Move cursor right one character.
  830.           [Ctrl]-[E] - cmLineUp       Move cursor up one line.
  831.           [Ctrl]-[F] - cmWordRight    Move cursor right to next word.
  832.           [Ctrl]-[G] - cmDelChar      Delete character cursor is on.
  833.           [Ctrl]-[H] - cmBackSpace    Delete character to left of cursor.
  834.           [Ctrl]-[I] - cmTabKey       Move right to next tab position.
  835.       [Ctrl]-[J]-[L] - cmJumpLine     Jump to a line number.
  836. *     [Ctrl]-[K]-[#] - cmSetMark0-9   Set place marker (0 to 9).
  837.       [Ctrl]-[K]-[B] - cmStartSelect  Begin selecting text.
  838.       [Ctrl]-[K]-[C] - cmPaste        Copy text from clipboard into document.
  839.       [Ctrl]-[K]-[D] - cmSaveDone     Save document and exit editor immediately.
  840.       [Ctrl]-[K]-[F] - cmSaveAs       Save current document to another file.
  841.       [Ctrl]-[K]-[H] - cmHideSelect   Hide selected text.
  842.       [Ctrl]-[K]-[K] - cmCopy         Copy text from document into clipboard.
  843.       [Ctrl]-[K]-[S] - cmSave         Save document and continue editing.
  844.       [Ctrl]-[K]-[T] - cmSelectWord   Select current word cursor is on.
  845.       [Ctrl]-[K]-[Y] - cmCut          Remove text from document into clipboard.
  846.       [Ctrl]-[K]-[X] - cmSaveDone     Save document and exit editor immediately.
  847.           [Ctrl]-[L] - cmSearchAgain  Continue searching for specified text.
  848.           [Ctrl]-[M] - cmNewLine      Enter CR/LF pair.
  849.           [Ctrl]-[N] - cmInsertLine   Add CR/LF pair AT cursor and keep cursor position.
  850.       [Ctrl]-[O]-[C] - cmCenterText   Center text on cursor line.
  851.       [Ctrl]-[O]-[I] - cmSetTabs      Set tab positions.
  852.       [Ctrl]-[O]-[R] - cmRightMargin  Set right margin position of line.
  853.       [Ctrl]-[O]-[W] - cmWordWrap     Toggle word wrap mode on or off.
  854. *     [Ctrl]-[Q]-[#] - cmJumpMark0-9  Move cursor to specified place marker (0 to 9).
  855.       [Ctrl]-[Q]-[A] - cmReplace      Search for text and replace it.
  856.       [Ctrl]-[Q]-[C] - cmTextEnd      Move cursor to end of document.
  857.       [Ctrl]-[Q]-[D] - cmLineEnd      Move cursor to end of line.
  858.       [Ctrl]-[Q]-[F] - cmFind         Find specified text.
  859.       [Ctrl]-[Q]-[H] - cmDelStart     Delete text from cursor to start of line.
  860.       [Ctrl]-[Q]-[I] - cmIndentMode   Toggle IndentMode on and off.
  861.       [Ctrl]-[Q]-[R] - cmTextStart    Move cursor to beginning of document.
  862.       [Ctrl]-[Q]-[S] - cmLineStart    Move cursor to beginning of line
  863.       [Ctrl]-[Q]-[U] - cmReformDoc    Reformat the document text.
  864.       [Ctrl]-[Q]-[Y] - cmDelEnd       Delete text from cursor to end of line.
  865.           [Ctrl]-[R] - cmPageUp       Page up one screen.
  866.           [Ctrl]-[S] - cmCharLeft     Move cursor left one character.
  867.           [Ctrl]-[T] - cmDelWord      Delete text from current cursor to next word.
  868.           [Ctrl]-[U] - cmUndo         Restore text to previous state.
  869.           [Ctrl]-[V] - cmInsMode      Toggle cursor between insert and overstrike mode.
  870.           [Ctrl]-[W] - cmScrollUp     Scroll screen up one line keeping cursor position.
  871.           [Ctrl]-[X] - cmLineDown     Move cursor down one line.
  872.           [Ctrl]-[Y] - cmDelLine      Delete line of text cursor is on.
  873.           [Ctrl]-[Z] - cmScrollDown   Scroll screen down one line keeping cursor position.
  874.          [Backspace] - cmBackspace    Delete character to left of cursor.
  875.         [Left Arrow] - cmCharLeft     Move cursor left one character.
  876.        [Right Arrow] - cmCharRight    Move cursor right one character.
  877.  [Ctrl]-[Left Arrow] - cmWordLeft     Move cursor left to previous word.
  878. [Ctrl]-[Right Arrow] - cmWordRight    Move cursor right to next word.
  879.               [Home] - cmLineStart    Move cursor to start of line.
  880.                [End] - cmLineEnd      Move cursor to end of line.
  881.        [Ctrl]-[Home] - cmHomePage     Move cursor to top of current page.
  882.         [Ctrl]-[End] - cmEndPage      Move cursor to bottom of current page.
  883.           [Up Arrow] - cmLineUp       Move cursor up one line.
  884.         [Down Arrow] - cmLineDown     Move cursor down one line.
  885.               [PgUp] - cmPageUp       Page up one screen.
  886.               [PgDn] - cmPageDown     Page down one screen.
  887.        [Ctrl]-[PgUp] - cmTextStart    Move cursor to beginning of document.
  888.        [Ctrl]-[PgDn] - cmTextEnd      Move cursor to end of document.
  889.                [Ins] - cmInsMode      Toggle cursor between insert and overstrike mode.
  890.                [Del] - cmDelChar      Delete character cursor is on or selected text.
  891.   [Ctrl]-[BackSpace] - cmDelStart     Delete text from cursor to start of line.
  892.        [Shift]-[Ins] - cmPaste        Copy text from clipboard into document.
  893.        [Shift]-[Del] - cmCut          Remove text from document into clipboard.
  894.         [Ctrl]-[Ins] - cmCopy         Copy text from document into clipboard.
  895.         [Ctrl]-[Del] - cmClear        Clear out and dispose of clipboard contents.
  896.  
  897. * NOTE:  # implies a numeric value between 1 and 0 on the
  898.          keyboard.  (i.e., 1, 2, 3, 4, 5, 6, 7, 8, 9, 0)
  899.  
  900.  
  901.  
  902. IDE COMMANDS NOT SUPPORTED
  903. --------------------------
  904.  
  905. [Ctrl]-[I]     - Insert a real tab character.
  906. [Ctrl]-[K]-[I] - Indent marked block.
  907. [Ctrl]-[K]-[P] - Print marked block
  908. [Ctrl]-[K]-[R] - Read a file from disk and insert into document as marked block.
  909. [Ctrl]-[K]-[U] - Unindent marked block.
  910. [Ctrl]-[K]-[V] - Move marked block.
  911. [Ctrl]-[K]-[W] - Write marked block to a file on disk.
  912. [Ctrl]-[O]-[T] - Toggle between real tabs and spaced tabs.
  913. [Ctrl]-[P]-[?] - Insert a control character (where ? is the character).
  914.  
  915.  
  916.  
  917. COMMANDS THAT DIFFER FROM IDE
  918. -----------------------------
  919.  
  920. Command              NewEdit                            IDE
  921. -------              -------                            ---
  922.  
  923. [Ctrl]-[K]-[F]     - Save document to a new file.       ----
  924. [Ctrl]-[O]-[I]     - Set tab stops                      Toggle AutoIndent Mode
  925. [Ctrl]-[Q]-[I]     - Toggle AutoIndent Mode             ----
  926. [Ctrl]-[BackSpace] - Delete from cursor to left margin. ----
  927. UNDO Menu Option   - Restore the line.                  [Ctrl]-[Q]-[L]
  928.  
  929.  
  930.  
  931. HOW TO ADD CUSTOM KEY COMMANDS
  932. ------------------------------
  933.  
  934. Adding your own custom key commands, and supporting code, is an
  935. easy matter.  The only requirement is you must understand how
  936. the different key arrays are structured.  As an example, we'll
  937. consider adding user print controls to the editor.
  938.  
  939. We start with the FirstKeys array.  Note the array size in the
  940. following code fragment:
  941.  
  942.   FirstKeys : array[0..46 * 2] of Word = (46, Ord (^A), cmWordLeft,
  943.  
  944. The array has 46 elements.  Each element is a word (two bytes).
  945. That's what the 46 * 2 means.  This is important, for it is how
  946. the editor determines which key stroke, or control sequence has
  947. been pressed.
  948.  
  949. You will note that FirstKeys consists entirely of control key
  950. sequences, ^A, ^B, ^C, etc.  To each control key a command is
  951. tied, cmWordLeft, cmReformPara, cmPageDown, etc.  Not only are
  952. control keys found in this array, but also cursor control keys
  953. like kbHome, kbEnd, kbUp, etc.  So far, it's pretty simple.
  954.  
  955. Now, notice that three control keys have a hex word value
  956. assigned to them, ^Q=$FF01, ^K=$FF02, ^O=$FF03, ^J=$FF04.
  957. Just what are these word values?  They are flags that let the
  958. NEWEDIT unit know when a special control sequence has been
  959. pressed that requires further evaluation of an additional key
  960. to complete the command.  For example, ^QI, ^KB, ^OR, or ^JL.
  961. How does it work?
  962.  
  963. The answer is the high byte in the command tied to the keystroke,
  964. which is $FF for these four special keys.  This is a flag that
  965. tells the ConvertEvent procedure to process the key AFTER the
  966. control key as the actual command.  How does it process it?  To
  967. answer that question, we need to dig into the other arrays
  968. first.
  969.  
  970. Notice that after the FirstKeys array there are several other
  971. arrays:  QuickKeys, BlockKeys, FormatKeys, JumpKeys, and
  972. finally KeyMap. The QuickKeys, BlockKeys, FormatKeys, and
  973. JumpKeys are arrays that are tied to the ^Q, ^K, ^O, and ^J
  974. keys. These arrays define the possible key commands that could
  975. be tied to these keys.  To illustrate this, note that FormatKey
  976. defines all the valid keystrokes allowed for the ^O command in
  977. FirstKeys.
  978.  
  979. The factor that ties the FormatKey array to the ^O command in
  980. the FirstKeys array is the low byte in the $FF01 command tied
  981. to ^O.  How does this work?  Very simply put, the order you
  982. place your array into the KeyMap array is the determining
  983. factor.  Let's look at KeyMap.
  984.  
  985.   KeyMap : array[0..4] of Pointer = (@FirstKeys,
  986.                                      @QuickKeys,
  987.                                      @BlockKeys,
  988.                                      @FormatKeys,
  989.                                      @JumpKeys);
  990.  
  991. Note the order of the array elements in Keymap, and the low
  992. byte of the commands tied to the control keys we've been
  993. discussing.
  994.  
  995.   0  FirstKeys
  996.   1  QuickKeys  ^Q  $FF01
  997.   2  BlockKeys  ^K  $FF02
  998.   3  FormatKeys ^O  $FF03
  999.   4  JumpKeys   ^J  $FF04
  1000.  
  1001. Do you see the relation?  When ConvertEvent sees the $FF as the
  1002. high byte in the word of the event, it knows that one of these
  1003. special control key values has been pressed.  It then looks for
  1004. the low byte of the word, and jumps into the KeyMap array to
  1005. determine the address of the Pointer to the proper array to get
  1006. the next key interpretation from, based on the position in the
  1007. KeyMap array corresponding to the low byte.  It then goes to
  1008. that array, finds the correct key, and processes it.  For
  1009. example,
  1010.  
  1011.   ^OR
  1012.  
  1013.   1)  ^O pressed, look it up in FirstKeys.
  1014.   2)  command is $FF03.
  1015.   3)  ConvertEvent finds $FF in the high byte of the word.
  1016.   4)  ConvertEvent knows more data follows and finds the low
  1017.       byte of the command word.
  1018.   5)  The low byte is $03 so ConvertEvent accesses the 3rd
  1019.       element of KeyMap to find the address of FormatKeys.
  1020.   6)  "R" is found in FormatKeys and the command tied to it,
  1021.       cmRightMargin, is placed on the event queue for
  1022.       HandleEvent to process.
  1023.  
  1024. So, how do we add new commands tied to the ^P key for printing
  1025. options?
  1026.  
  1027. First, define some new commands up in the constant area where
  1028. the cm??? commands are defined.  Let's say we want ^PD to print
  1029. the entire document and ^PC to print the document starting at
  1030. the current cursor position.  So we add new commands called
  1031. cmPrintStart and cmPrintCurrent and assign them a value not
  1032. being used by other cm??? commands.  So far, so good
  1033.  
  1034. Second we go to the FirstKeys array and insert ^P as a new
  1035. command.  We have to change the array size (46) to show we
  1036. have a new command (change 46 to 47 -- BOTH 46's to 47's).  Now
  1037. tie a new command to ^P, in this case it would be $FF05.  So,
  1038. we would have something like this:
  1039.  
  1040. CONST
  1041.  ...
  1042.  cmPrintFirst   = 550
  1043.  cmPrintCurrent = 551
  1044.  
  1045.   FirstKeys : array[0..46 * 2] of Word = (46, Ord (^A),    cmWordLeft,
  1046.                                               Ord (^B),    cmReformPara,
  1047.                                               Ord (^C),    cmPageDown,
  1048.                                               Ord (^D),    cmCharRight,
  1049.                                               Ord (^E),    cmLineUp,
  1050.                                               Ord (^F),    cmWordRight,
  1051.                                               Ord (^G),    cmDelChar,
  1052.                                               Ord (^H),    cmBackSpace,
  1053.                                               Ord (^I),    cmTabKey,
  1054.                                               Ord (^J),    $FF04,,
  1055.                                               Ord (^K),    $FF02,
  1056.                                               Ord (^L),    cmSearchAgain,
  1057.                                               Ord (^M),    cmNewLine,
  1058.                                               Ord (^N),    cmInsertLine,
  1059.                                               Ord (^O),    $FF03,
  1060.                                               Ord (^P),    $FF05,
  1061.                                               ....
  1062.  
  1063. Now we create a new array to hold the print commands.  We'll
  1064. call it PrintKeys.
  1065.  
  1066.   PrintKeys : array[0..2 * 2] of Word = (2,  Ord ('C'), cmPrintCurrent,
  1067.                                              Ord ('D'), cmPrintStart);
  1068.  
  1069. Last of all we add PrintKeys to the 5th ($FF05) position in
  1070. KeyMap. Don't forget to change the array range from 4 to 5!
  1071.  
  1072.   KeyMap : array[0..5] of Pointer = (@FirstKeys,
  1073.                                      @QuickKeys,
  1074.                                      @BlockKeys,
  1075.                                      @FormatKeys,
  1076.                                      @JumpKeys,
  1077.                                      @PrintKeys);
  1078.  
  1079. Now, all you need do is add the cmPrintStart and cmPrintCurrent
  1080. commands to HandleEvent, with the appropriate procedure or
  1081. function call.  Coding these procedures or functions is up to
  1082. you!  Don't forget to include the declaration for the procedure
  1083. or function inside private portion the TEditor object!
  1084.  
  1085. Heck!  Here's some code Steve Schafer posted on BPROGA that I modified to
  1086. conform to my coding style.  It should get you started.
  1087.  
  1088.  
  1089.         uses ... Printer;
  1090.  
  1091.         procedure TEditor.Print_Document;
  1092.  
  1093.         VAR
  1094.  
  1095.           P: Word;                      { Position of CurPtr.          }
  1096.  
  1097.         begin
  1098.  
  1099.           for P := 0 to BufLen do       { Print from beginning to end. }
  1100.  
  1101.             Write (Lst, BufChar (P));   { Print the character.         }
  1102.  
  1103.         end { TEditor.Print_Document };
  1104.